package com.xbts.system.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaweicloud.sdk.bss.v2.model.ListRateOnPeriodDetailRequest;
import com.huaweicloud.sdk.bss.v2.model.PeriodProductInfo;
import com.huaweicloud.sdk.bss.v2.model.RateOnPeriodReq;
import com.huaweicloud.sdk.core.utils.JsonUtils;
import com.huaweicloud.sdk.ecs.v2.model.*;
import com.huaweicloud.sdk.vpc.v2.model.ListVpcsResponse;
import com.xbts.common.constant.UserConstants;
import com.xbts.common.core.domain.Setting;
import com.xbts.common.core.domain.model.LoginUser;
import com.xbts.common.core.redis.RedisCache;
import com.xbts.common.enums.SettingEnum;
import com.xbts.common.exception.ServiceException;
import com.xbts.common.utils.DateUtils;
import com.xbts.common.utils.SecurityUtils;
import com.xbts.common.utils.SnowFlakeUtil;
import com.xbts.common.utils.StringUtils;
import com.xbts.system.domain.*;
import com.xbts.system.domain.dto.*;
import com.xbts.common.enums.ShoppingCarEnums;
import com.xbts.system.domain.vo.SysUserControlVO;
import com.xbts.system.enums.OrderStatusEnum;
import com.xbts.system.mapper.CnShoppingCarMapper;
import com.xbts.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 购物车Service业务层处理
 *
 * @author xbts
 * @date 2023-08-03
 */
@Service
public class CnShoppingCarServiceImpl extends ServiceImpl<CnShoppingCarMapper, CnShoppingCar> implements ICnShoppingCarService {

    @Autowired
    private ICloudServiceService cloudServiceService;

    @Autowired
    private SettingService settingService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ICnGovernmentCloudService cnGovernmentCloudService;

    @Autowired
    private ICnCloudMarketSkuService cnCloudMarketSkuService;

    @Autowired
    private ICnCloudMarketService cnCloudMarketService;

    @Autowired
    private ICnUserCloudServersRelationService cnUserCloudServersRelationService;

    @Autowired
    private ICnOrderItemService cnOrderItemService;

    /**
     * 查询购物车列表
     *
     * @param cnShoppingCar 购物车
     * @return 购物车
     */
    @Override
    public List<CnShoppingCar> selectCnShoppingCarList(CnShoppingCar cnShoppingCar) {
        LambdaUpdateWrapper<CnShoppingCar> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (!loginUser.getUser().getUserType().equals(UserConstants.USER_TYPE_MANAGER)) {// 不是管理员,只能查询自己的购物车
            lambdaUpdateWrapper.eq(CnShoppingCar::getUserId, SecurityUtils.getUserId());
        }
        lambdaUpdateWrapper.and(StringUtils.isNotEmpty(cnShoppingCar.getSearchValue()), v -> {

            v.like(CnShoppingCar::getShoppingCarId, cnShoppingCar.getSearchValue())
                    .or().like(CnShoppingCar::getRegionId, cnShoppingCar.getSearchValue())
                    .or().like(CnShoppingCar::getOrderAbstract, cnShoppingCar.getSearchValue());
        });
        if(StringUtils.isNotNull(cnShoppingCar.getShoppingCarEnums())){
            lambdaUpdateWrapper.eq(CnShoppingCar::getShoppingCarEnums, cnShoppingCar.getShoppingCarEnums().name());
        }
        // 倒序
        lambdaUpdateWrapper.orderByDesc(CnShoppingCar::getCreateTime);
        return list(lambdaUpdateWrapper);
    }

    /**
     * 查询购物车
     *
     * @param shoppingCarId 购物车主键
     * @return 购物车
     */
    @Override
    public CnShoppingCar selectCnShoppingCarByShoppingCarId(String shoppingCarId) {
        return getById(shoppingCarId);
    }

    /**
     * 新增购物车
     *
     * @param cnShoppingCar 购物车
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertCnShoppingCar(CnShoppingCar cnShoppingCar) {

        SysUserControlVO user = userService.getUserInfo(SecurityUtils.getUserId());

        if(1 != user.getAuthentication()){
            throw new ServiceException("请先认证!");
        }

        if (cnShoppingCar.getShoppingCarEnums().equals(ShoppingCarEnums.CLOUD_SERVER) && StringUtils.isEmpty(cnShoppingCar.getJsonStr())) {
            throw new ServiceException("云服务器参数不能为空");
        } else if ((cnShoppingCar.getShoppingCarEnums().equals(ShoppingCarEnums.CLOUD_MARKET)
                || cnShoppingCar.getShoppingCarEnums().equals(ShoppingCarEnums.GOV_CLOUD))
                && StringUtils.isEmpty(cnShoppingCar.getRelationId())) {
            throw new ServiceException("模板ID不能为空");
        }
        String priceKey = cnShoppingCar.getPriceKey();
//        if (cnShoppingCar.getShoppingCarEnums().equals(ShoppingCarEnums.CLOUD_MARKET) && StringUtils.isNull(cnShoppingCar.getMarketSkuId())) {
//            throw new ServiceException("云市场Sku不能为空");
//        }
        if(cnShoppingCar.getShoppingCarEnums().equals(ShoppingCarEnums.CLOUD_SERVER)) {
            // 判断服务器购买参数
            cloudServer(cnShoppingCar.getJsonStr());

            // 获取可变更的参数的价格
            getVariableParameterPrice(cnShoppingCar, priceKey);


        } else if(cnShoppingCar.getShoppingCarEnums().equals(ShoppingCarEnums.GOV_CLOUD)){
            CnGovernmentCloud governmentCloud = cnGovernmentCloudService.getById(cnShoppingCar.getRelationId());
            cnShoppingCar.setOriginalPrice(governmentCloud.getPrice());
            cnShoppingCar.setUpdatePrice(governmentCloud.getPrice());
            Integer billingMode = governmentCloud.getBillingMode();
            String billingModeStr = "年";
            if(billingMode == 0){
                billingModeStr = "次";
            } else if (billingMode == 1){
                billingModeStr = "天";
            } else if (billingMode == 30){
                billingModeStr = "月";
            } else if (billingMode == 365){
                billingModeStr = "年";
            }
            cnShoppingCar.setRelationId(cnShoppingCar.getRelationId());
            cnShoppingCar.setPeriodType(governmentCloud.getBillingMode());
            cnShoppingCar.setOrderAbstract("【" + governmentCloud.getServerName() + "】 " + cnShoppingCar.getPeriodNum() + billingModeStr );
        } else if(cnShoppingCar.getShoppingCarEnums().equals(ShoppingCarEnums.CLOUD_MARKET)){
            cnShoppingCar.setMarketSkuId(Long.valueOf(cnShoppingCar.getRelationId()));
            CnCloudMarketSku marketSku = cnCloudMarketSkuService.getById(cnShoppingCar.getRelationId());
            CnCloudMarket cloudMarket = cnCloudMarketService.getById(marketSku.getMarketId());
            String billingMode = marketSku.getCloudMarketBuyingMethod();
            String billingModeStr = "年";
            if(billingMode.equals("0")){
                billingModeStr = "次";
            } else if (billingMode.equals("1")){
                billingModeStr = "天";
            } else if (billingMode.equals("30")){
                billingModeStr = "月";
            } else if (billingMode.equals("365")){
                billingModeStr = "年";
            }
            cnShoppingCar.setPeriodType(Integer.valueOf(marketSku.getCloudMarketBuyingMethod()));
            cnShoppingCar.setOriginalPrice(marketSku.getPrice());
            cnShoppingCar.setUpdatePrice(marketSku.getPrice());
            cnShoppingCar.setOrderAbstract("【" + cloudMarket.getTitle() + "-" + marketSku.getFirstSkuName() + "" + (StringUtils.isNotEmpty(marketSku.getSecondSkuName()) ? ("-" + marketSku.getSecondSkuName()) : "")  + "】 " + cnShoppingCar.getPeriodNum() + billingModeStr);
        } else if (cnShoppingCar.getShoppingCarEnums().equals(ShoppingCarEnums.CLOUD_SERVER_CHANGE)) {

            String jsonStr = cnShoppingCar.getJsonStr();
            JSONObject jsonObject = JSON.parseObject(jsonStr);
            String id = jsonObject.getString("id");
            CnUserCloudServersRelation userCloudServersRelation = cnUserCloudServersRelationService.getById(id);
            // 保存服务器标识
            cnShoppingCar.setRegionId(userCloudServersRelation.getRegionId());
            cnShoppingCar.setRelationId(userCloudServersRelation.getRelationId());

            // 判断是否存在未完成的订单
            long carCount = this.count(new LambdaQueryWrapper<CnShoppingCar>()
                    .eq(CnShoppingCar::getShoppingCarEnums, cnShoppingCar.getShoppingCarEnums().name())
                    .eq(CnShoppingCar::getRegionId, userCloudServersRelation.getRegionId()));
            if (carCount > 0) {
                throw new ServiceException("购物车中存在该服务器待支付的变更订单！");
            }
            long orderCount = cnOrderItemService.count(new LambdaQueryWrapper<CnOrderItem>()
                    .eq(CnOrderItem::getRegionId, userCloudServersRelation.getRegionId())
                    .eq(CnOrderItem::getShoppingCarEnums, cnShoppingCar.getShoppingCarEnums().name())
                    .eq(CnOrderItem::getOrderStatus, OrderStatusEnum.IN_PROGRESS.name()));
            if (orderCount > 0) {
                throw new ServiceException("该服务器存在待审核的变更订单！");
            }

            // 获取可变更的参数的价格
            getVariableParameterPriceForChange(cnShoppingCar, priceKey);
        } else if (cnShoppingCar.getShoppingCarEnums().equals(ShoppingCarEnums.CLOUD_SERVER_RENEW)) {
            String jsonStr = cnShoppingCar.getJsonStr();
            JSONObject jsonObject = JSON.parseObject(jsonStr);
            String periodType = jsonObject.getString("period_type");
            if (StringUtils.isEmpty(periodType) || (!StringUtils.equals("2", periodType) && StringUtils.equals("3", periodType))) {
                throw new ServiceException("续费类型异常！");
            }
            String id = jsonObject.getString("id");
            CnUserCloudServersRelation userCloudServersRelation = cnUserCloudServersRelationService.getById(id);

            // 判断是否存在未完成的订单
            long carCount = this.count(new LambdaQueryWrapper<CnShoppingCar>()
                    .eq(CnShoppingCar::getShoppingCarEnums, cnShoppingCar.getShoppingCarEnums().name())
                    .eq(CnShoppingCar::getRegionId, userCloudServersRelation.getRegionId()));
            if (carCount > 0) {
                throw new ServiceException("购物车中存在该服务器待支付的续费订单！");
            }
            long orderCount = cnOrderItemService.count(new LambdaQueryWrapper<CnOrderItem>()
                    .eq(CnOrderItem::getRegionId, userCloudServersRelation.getRegionId())
                    .eq(CnOrderItem::getShoppingCarEnums, cnShoppingCar.getShoppingCarEnums().name())
                    .eq(CnOrderItem::getOrderStatus, OrderStatusEnum.IN_PROGRESS.name()));
            if (orderCount > 0) {
                throw new ServiceException("该服务器存在待审核的续费订单！");
            }

            String periodNum = jsonObject.getString("period_num");
            periodType = periodType.equals("2") ? "月" : "年";

            cnShoppingCar.setRegionId(userCloudServersRelation.getRegionId());
            cnShoppingCar.setRelationId(userCloudServersRelation.getRelationId());
            cnShoppingCar.setOrderAbstract("服务器:" + userCloudServersRelation.getRelationId() + "续费-" + periodNum + periodType);
            cnShoppingCar.setPeriodNum(Integer.valueOf(periodNum));
            cnShoppingCar.setPeriodType(periodType.equals("月") ? 30 : 365);
            // 获取可变更的参数的价格
            getVariableParameterPrice(cnShoppingCar, priceKey);
        }



        // 获取折扣
        Setting setting = settingService.get(SettingEnum.DISCOUNT_SETTING.name());
        DiscountSetting discountSetting = null;
        if (setting != null) {
            discountSetting = JSONObject.parseObject(setting.getSettingValue(), DiscountSetting.class);
        }
        int discount = discountSetting.getDiscount(); // 折扣


        if(StringUtils.isNull(cnShoppingCar.getPeriodNum())){
            cnShoppingCar.setPeriodNum(1);
        }
        BigDecimal originalPrice = cnShoppingCar.getOriginalPrice().multiply(new BigDecimal(cnShoppingCar.getPeriodNum())); // 原价
        cnShoppingCar.setOriginalPrice(originalPrice);

        Long shoppingCarId = SnowFlakeUtil.getSnowFlakeId(); // 购物车id
        cnShoppingCar.setShoppingCarId(shoppingCarId.toString());

        // originalPrice判断是否大于0
        if (originalPrice.compareTo(BigDecimal.ZERO) >= 0) {
            // 修改价格
            BigDecimal updatePrice = originalPrice.multiply(new BigDecimal(discount)).divide(new BigDecimal(10));
            // 计算优惠价
            cnShoppingCar.setDiscountPrice(originalPrice.subtract(updatePrice));
            cnShoppingCar.setUpdatePrice(updatePrice);
            cnShoppingCar.setDiscount(discount);

            if(cnShoppingCar.getShoppingCarEnums().equals(ShoppingCarEnums.CLOUD_SERVER) || cnShoppingCar.getShoppingCarEnums().equals(ShoppingCarEnums.CLOUD_SERVER_CHANGE)){
                // 三个可变更的参数的实际支付价格
                cnShoppingCar.setEc2Price(cnShoppingCar.getEc2Price().multiply(new BigDecimal(discount)).divide(new BigDecimal(10)));
                cnShoppingCar.setEbsPrice(cnShoppingCar.getEbsPrice().multiply(new BigDecimal(discount)).divide(new BigDecimal(10)));
                cnShoppingCar.setVpcPrice(cnShoppingCar.getVpcPrice().multiply(new BigDecimal(discount)).divide(new BigDecimal(10)));
            }
        }
        cnShoppingCar.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        cnShoppingCar.setUserId(SecurityUtils.getUserId());
        return save(cnShoppingCar);
    }

    private void getVariableParameterPriceForChange(CnShoppingCar cnShoppingCar, String priceKey) {
        if(StringUtils.isBlank(priceKey)){
            throw new ServiceException("异常请求！请刷新页面！");
        }
        Map<String, Object> cacheMap = redisCache.getCacheObject(priceKey);
        if (StringUtils.isNull(cacheMap)){
            throw new ServiceException("异常请求！请刷新页面！");
        }
        BigDecimal price = (BigDecimal)cacheMap.get("price");
        Integer type = (Integer)cacheMap.get("type");
        cnShoppingCar.setOriginalPrice(price);

        // 订单摘要
        String orderAbstract = (String)cacheMap.get("orderAbstract");
        if(StringUtils.isNotBlank(orderAbstract)) {
            cnShoppingCar.setOrderAbstract(orderAbstract);
        }

        BigDecimal ec2Price = BigDecimal.ZERO;
        BigDecimal ebsPrice = BigDecimal.ZERO;
        BigDecimal vpcPrice = BigDecimal.ZERO;

        if(type == 1){
            ec2Price = (BigDecimal)cacheMap.get("price");
        }
        if(type == 2){
            ebsPrice = (BigDecimal)cacheMap.get("price");
        }
        if(type == 3){
            vpcPrice = (BigDecimal)cacheMap.get("price");
        }
        cnShoppingCar.setEc2Price(ec2Price);
        cnShoppingCar.setEbsPrice(ebsPrice);
        cnShoppingCar.setVpcPrice(vpcPrice);

        cnShoppingCar.setPriceQueryJsonStr((String)cacheMap.get("priceQueryJsonStr"));
    }
    private void getVariableParameterPrice(CnShoppingCar cnShoppingCar, String priceKey) {
        if(StringUtils.isBlank(priceKey)){
            throw new ServiceException("异常请求！请刷新页面！");
        }
        Map<String, Object> cacheMap = redisCache.getCacheObject(priceKey);
        if (StringUtils.isNull(cacheMap)){
            throw new ServiceException("异常请求！请刷新页面！");
        }
        BigDecimal price = (BigDecimal)cacheMap.get("price");
        cnShoppingCar.setOriginalPrice(price);

        // 订单摘要
        String orderAbstract = (String)cacheMap.get("orderAbstract");
        if(StringUtils.isNotBlank(orderAbstract)) {
            cnShoppingCar.setOrderAbstract(orderAbstract);
        }

        String priceQueryJsonStr = (String)cacheMap.get("priceQueryJsonStr");
//        RateOnPeriodReqDTO dto = JSONObject.parseObject(priceQueryJsonStr, RateOnPeriodReqDTO.class);
//        List<PeriodProductInfo> productInfos = dto.getProductInfos();
        List<PeriodProductInfo> productInfos = JSONArray.parseArray(priceQueryJsonStr, PeriodProductInfo.class);
        RateOnPeriodReq req = new RateOnPeriodReq();
        req.setProductInfos(productInfos);

        List<PeriodProductInfo> ec2List = productInfos.stream().filter(item -> item.getResourceType().equals("hws.resource.type.vm")).collect(Collectors.toList());
        List<PeriodProductInfo> ebsList = productInfos.stream().filter(item -> item.getResourceType().equals("hws.resource.type.volume")).collect(Collectors.toList());
        List<PeriodProductInfo> vpcList = productInfos.stream().filter(item -> item.getResourceType().equals("hws.resource.type.bandwidth")).collect(Collectors.toList());

        BigDecimal ec2Price = BigDecimal.ZERO;
        BigDecimal ebsPrice = BigDecimal.ZERO;
        BigDecimal vpcPrice = BigDecimal.ZERO;

        if(ec2List.size() != 0){
            RateOnPeriodReqDTO ec2Dto = new RateOnPeriodReqDTO();
            ec2Dto.setProductInfos(ec2List);
            Map<String, Object> stringObjectMap = cloudServiceService.listRateOnPeriodDetail(ec2Dto);
            ec2Price = (BigDecimal)stringObjectMap.get("price");
        }
        if(ebsList.size() != 0){
            RateOnPeriodReqDTO ebsDto = new RateOnPeriodReqDTO();
            ebsDto.setProductInfos(ebsList);
            Map<String, Object> stringObjectMap = cloudServiceService.listRateOnPeriodDetail(ebsDto);
            ebsPrice = (BigDecimal)stringObjectMap.get("price");
        }
        if(vpcList.size() != 0){
            RateOnPeriodReqDTO vpcDto = new RateOnPeriodReqDTO();
            vpcDto.setProductInfos(vpcList);
            Map<String, Object> stringObjectMap = cloudServiceService.listRateOnPeriodDetail(vpcDto);
            vpcPrice = (BigDecimal)stringObjectMap.get("price");
        }
        cnShoppingCar.setEc2Price(ec2Price);
        cnShoppingCar.setEbsPrice(ebsPrice);
        cnShoppingCar.setVpcPrice(vpcPrice);

        cnShoppingCar.setPriceQueryJsonStr(JSON.toJSONString(req));
    }

    /**
     * 判断华为云购买的参数是否符合华为云
     * @param jsonStr 服务器购买json
     */
    private void cloudServer(String jsonStr) {
        PrePaidServer prePaidServer = JsonUtils.toObject(jsonStr, PrePaidServer.class);
        String imageRef = prePaidServer.getImageRef();
        String flavorRef = prePaidServer.getFlavorRef();
        String vpcId = prePaidServer.getVpcid();
        List<PrePaidServerNic> nics = prePaidServer.getNics();
        PrePaidServerRootVolume rootVolume = prePaidServer.getRootVolume();
        String name = prePaidServer.getName();
        if (StringUtils.isEmpty(imageRef)){
            throw new ServiceException("系统镜像不能为空");
        }
        if (StringUtils.isEmpty(flavorRef)){
            throw new ServiceException("系统规格的ID不能为空");
        }
        if (StringUtils.isEmpty(vpcId)){
            ListVpcsResponse listVpcsResponse = cloudServiceService.listVpcs("");
            if(listVpcsResponse.getVpcs().size() > 0){
                prePaidServer.setVpcid(listVpcsResponse.getVpcs().get(0).getId());
            }
            throw new ServiceException("虚拟私有云不能为空");
        }
        if (StringUtils.isEmpty(nics)){
            throw new ServiceException("网卡信息不能为空");
        }
        for (PrePaidServerNic nic : nics) {
            String subnetId = nic.getSubnetId();
            if (StringUtils.isEmpty(subnetId)){
                throw new ServiceException("子网的网络ID不能为空");
            }
        }
        if (StringUtils.isNull(rootVolume)){
            throw new ServiceException("系统盘不能为空");
        }
        if (StringUtils.isNull(rootVolume.getVolumetype())){
            throw new ServiceException("磁盘类型不能为空");
        }
        if (StringUtils.isEmpty(name)){
            throw new ServiceException("服务器名称不能为空");
        }
        // 服务器名称正则验证
        if (!name.matches("^[\\u4e00-\\u9fa5_a-zA-Z0-9-]{1,64}$")){
            throw new ServiceException("服务器名称只能是中文、英文、数字、下划线且长度不能超过20");
        }
        if (StringUtils.isEmpty(prePaidServer.getAdminPass())){
            throw new ServiceException("密码不能为空");
        }
        // 密码正则表达式 长度为8-26位。
        //密码至少必须包含大写字母、小写字母、数字和特殊字符（!@$%^-_=+[{}]:,./?）中的三种。
        //密码不能包含用户名或用户名的逆序。
        //Windows系统密码不能包含用户名或用户名的逆序，不能包含用户名中超过两个连续字符的部分。
//        String regex = "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)(?=.*[!@$%^\\-_=+[{}]:,./?]).{8,26}$";
        String regex = "^(?![\\da-z]+$)(?![\\dA-Z]+$)(?![\\d!@$%\\^\\_=+\\[{}\\]:,\\./?~#*-]+$)(?![a-zA-Z]+$)(?![a-z!@$%\\^\\_=+\\[{}\\]:,\\./?~#*-]+$)(?![A-Z!@$%\\^\\_=+\\[{}\\]:,\\./?~#*-]+$)[\\da-zA-z!@$%\\^\\_=+\\[{}\\]:,\\./?~#*-]{8,26}$";
        if (!prePaidServer.getAdminPass().matches(regex)){
            throw new ServiceException("密码至少必须包含大写字母、小写字母、数字和特殊字符（!@$%^-_=+[{}]:,./?）中的三种");
        }
        if (prePaidServer.getCount() == null){
            throw new ServiceException("购买数量不能为空");
        }
        if (prePaidServer.getCount() < 1){
            throw new ServiceException("购买数量不能小于1");
        }

    }

    /**
     * 修改购物车
     *
     * @param cnShoppingCar 购物车
     * @return 结果
     */
    @Override
    public boolean updateCnShoppingCar(CnShoppingCar cnShoppingCar) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (!loginUser.getUser().getUserType().equals(UserConstants.USER_TYPE_MANAGER)) {
            throw new ServiceException("非管理员不能修改购物车");
        }
        CnShoppingCar bdCnShoppingCar = getById(cnShoppingCar.getShoppingCarId());

        // 优惠价格
        BigDecimal bigDecimal = bdCnShoppingCar.getOriginalPrice().subtract(cnShoppingCar.getUpdatePrice());

        cnShoppingCar.setUpdateBy(SecurityUtils.getUserId().toString());
        cnShoppingCar.setUpdateTime(DateUtils.getNowDate());
        cnShoppingCar.setDiscountPrice(bigDecimal);
        return updateById(cnShoppingCar);
    }

    /**
     * 批量删除购物车
     *
     * @param shoppingCarIds 需要删除的购物车主键
     * @return 结果
     */
    @Override
    public boolean deleteCnShoppingCarByShoppingCarIds(List<String> shoppingCarIds) {
        return removeBatchByIds(shoppingCarIds);
    }

    /**
     * 删除购物车信息
     *
     * @param shoppingCarId 购物车主键
     * @return 结果
     */
    @Transactional
    @Override
    public boolean deleteCnShoppingCarByShoppingCarId(String shoppingCarId) {
        return removeById(shoppingCarId);
    }

}
